package com.itlong.cloud.sdk.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.PropertySubscriberHanlerDTO;
import com.itlong.cloud.POJO.DTO.sdk.*;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.sdk.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.property.dao.IPropertyUnitInfoDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.sdk.dao.*;
import com.itlong.cloud.sdk.service.ICloudTalkSDKServerProjectService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 * 云对讲SDK项目服务层接口实现类
 * </desc>
 *
 * @createDate 2018/05/17
 */
@Service
@RefreshScope
public class CloudTalkSDKServerProjectServiceImpl implements ICloudTalkSDKServerProjectService {

    @Autowired
    private ICloudTalkSDKServerBuildDao iCloudTalkSDKServerBuildDao;

    @Autowired
    private ICloudTalkSDKServerUnitDao iCloudTalkSDKServerUnitDao;

    @Autowired
    private ICloudTalkSDKServerRoomDao iCloudTalkSDKServerRoomDao;

    @Autowired
    private ICloudTalkSDKServerSaveUserRoomDao iCloudTalkSDKServerSaveUserRoomDao;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private ISDKServerOldProjectDao iSDKProjectDao;

    @Autowired
    private ICloudTalkSDKServerProjectDao iCloudTalkSDKServerProjectDao;

    @Autowired
    private IPropertyUnitInfoDao iPropertyUnitInfoDao;

    @Value("${" + PlatformConstants.LYKZ_ACCOUNT_SID + "}")
    String LYKZ_ACCOUNT_SID;
    @Value("${" + PlatformConstants.LYKZ_ACCOUNT_TOKEN + "}")
    String LYKZ_ACCOUNT_TOKEN;
    @Value("${" + PlatformConstants.LYKZ_APPID + "}")
    String LYKZ_APPID;
    @Value("${" + PlatformConstants.LYKZ_SOFT_VERSION + "}")
    String LYKZ_SOFT_VERSION;
    @Value("${" + PlatformConstants.LYKZ_URL + "}")
    String LYKZ_URL;
    @Value("${" + PlatformConstants.LYKZ_PORT + "}")
    String LYKZ_PORT;

    /**
     * <desc>
     *      根据参数字段查询build_info信息
     * <desc/>
     *
     * @param param 查询参数集
     * @return List<BuildInfoPO> 返回对象集
     * @author wangzhi
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<BuildInfoPO> getBuildByParam(Map<String, Object> param) {
        if (param.size() > 0) {
            return iCloudTalkSDKServerBuildDao.getBuildByParam(param);
        }
        return null;
    }

    /**
     * <desc>
     *      更新项目楼栋信息
     * </desc>
     *
     * @param buildUpdates 待更新的PO对象集
     * @return 更新的数量
     * @author wangzhi
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateBuild(List<BuildInfoPO> buildUpdates) {
        try {
            List<Map<String, Object>> updateBuildList = new ArrayList<>();
            for (BuildInfoPO buildInfoPO : buildUpdates) {
                updateBuildList.add(SqlUtil.durableData(buildInfoPO, PlatformConstants.TABLE_UPDATE));
            }
            return iCloudTalkSDKServerBuildDao.batchUpdate(updateBuildList);
        } catch (Exception e) {
            throw new DataAccessException("【CloudTalk_SDK_build_update】更新楼栋异常", e);
        }
    }

    /**
     * <desc>
     *      保存项目楼栋信息
     * </desc>
     *
     * @param buildSaves 待保存的PO对象集
     * @return 保存的数量
     * @author wangzhi
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer saveBuild(List<BuildInfoPO> buildSaves) {
        try {
            List<Map<String, Object>> saveBuildList = new ArrayList<>();
            for (BuildInfoPO buildInfoPO : buildSaves) {
                saveBuildList.add(SqlUtil.durableData(buildInfoPO, PlatformConstants.TABLE_SAVE));
            }
            return iCloudTalkSDKServerBuildDao.batchSave(saveBuildList);
        } catch (Exception e) {
            throw new DataAccessException("【CloudTalk_SDK_build_update】保存楼栋异常", e);
        }
    }

    /**
     * <desc>
     *      根据参数字段查询unit_info信息
     * <desc/>
     *
     * @param param 查询参数集
     * @return List<UnitInfoPO> 返回对象集
     * @author wangzhi
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<UnitInfoPO> getUnitByParam(Map<String, Object> param) {
        if (param.size() > 0) {
            return iCloudTalkSDKServerUnitDao.getUnitByParam(param);
        }
        return null;
    }

    /**
     * <desc>
     *      更新项目单元信息
     * </desc>
     *
     * @param unitUpdates 待更新的PO对象
     * @return 更新的数量
     * @author wangzhi
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateUnit(List<UnitInfoPO> unitUpdates) {
        try {
            List<Map<String, Object>> updateUnitList = new ArrayList<>();
            for (UnitInfoPO unitInfoPO : unitUpdates) {
                updateUnitList.add(SqlUtil.durableData(unitInfoPO, PlatformConstants.TABLE_UPDATE));
            }
            int intRes =  iCloudTalkSDKServerUnitDao.batchUpdate(updateUnitList);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("projectId",unitUpdates.get(0).getProjectId());
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_FULL,jsonObject,unitUpdates.get(0).getProjectId());
            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",deviceBusinessChangeLogPOS);
            //云对讲业务指令
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

            return intRes;
        } catch (Exception e) {
            throw new DataAccessException("【CloudTalk_SDK_build_update】更新楼栋异常", e);
        }
    }

    /**
     * <desc>
     *      保存项目单元信息
     * </desc>
     *
     * @param unitSaves 待更新的PO对象
     * @return 更新的数量
     * @author wangzhi
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer saveUnit(List<UnitInfoPO> unitSaves) {
        try {
            List<Map<String, Object>> saveUnitList = new ArrayList<>();
            for (UnitInfoPO unitInfoPO : unitSaves) {
                Integer unitGroupNum = iPropertyUnitInfoDao.getMaxUnitGroupNum(unitInfoPO.getProjectId());
                if (unitGroupNum == null) {
                    unitGroupNum = saveUnitList.size() + 1;
                } else {
                    if (unitGroupNum < 99) {
                        unitGroupNum += (saveUnitList.size() + 1);
                    } else {
                        List<String> list = iPropertyUnitInfoDao.getUnitGroupNumGroupCountMap(unitInfoPO.getProjectId());
                        Map<String,Integer> map = new HashMap<>();
                        for (String str : list){
                            String[] split = str.split(",");
                            map.put(split[0],new Integer(split[1]));
                        }
                        if (map.get("99").equals(map.get("01"))) {
                            unitGroupNum = 1 + saveUnitList.size();
                        }
                        for (int i = 2; i <= 99; i++) {
                            if (!map.get(NumberHandlerUtil.numFormatToString(i, 2)).equals(map.get(NumberHandlerUtil.numFormatToString((i - 1), 2)))) {
                                unitGroupNum = i + saveUnitList.size();
                                break;
                            }
                        }
                    }
                }
                unitInfoPO.setUnitGroupNum(NumberHandlerUtil.numFormatToString((unitGroupNum % 99) == 0 ? 99 : (unitGroupNum % 99),2));
                saveUnitList.add(SqlUtil.durableData(unitInfoPO, PlatformConstants.TABLE_SAVE));
            }
            return iCloudTalkSDKServerUnitDao.batchSave(saveUnitList);
        } catch (Exception e) {
            throw new DataAccessException("【CloudTalk_SDK_build_update】更新楼栋异常", e);
        }
    }

    /**
     * <desc>
     *      根据参数字段查询room_info信息
     * </desc>
     *
     * @param param 查询参数集
     * @return List<RoomInfoPO>返回对象集
     * @author wangzhi
     * @createDate 2018/05/18
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<RoomInfoPO> getRoomByParam(Map<String, Object> param) {
        if (param.size() > 0) {
            return iCloudTalkSDKServerRoomDao.getRoomByParam(param);
        }
        return null;
    }

    /**
     * <desc>
     *      更新项目房间信息
     * </desc>
     *
     * @param roomUpdates 待更新的PO对象
     * @return 更新的数量
     * @author wangzhi
     * @createDate 2018/05/18
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateRoom(List<RoomInfoPO> roomUpdates) {
        try {
            JSONArray jsonArray = new JSONArray();
            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            List<Map<String, Object>> updateRoomList = new ArrayList<>();
            for (RoomInfoPO roomInfoPO : roomUpdates) {
                updateRoomList.add(SqlUtil.durableData(roomInfoPO, PlatformConstants.TABLE_UPDATE));
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("roomId",roomInfoPO.getRoomId());
                jsonArray.add(jsonObject);
            }
            int intRes = iCloudTalkSDKServerRoomDao.batchUpdate(updateRoomList);
            System.err.println(jsonArray);
            String projectId = roomUpdates.get(0).getProjectId();
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM,jsonArray,projectId);
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",deviceBusinessChangeLogPOS);
            // 发送消息队列
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

            return intRes;
        } catch (Exception e) {
            throw new DataAccessException("【CloudTalk_SDK_build_update】更新楼栋异常", e);
        }
    }

    /**
     * <desc>
     *      保存项目房间信息
     * </desc>
     *
     * @param roomSaves 待保存的PO对象
     * @return 更新的数量
     * @author wangzhi
     * @createDate 2018/05/18
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer saveRoom(List<RoomInfoPO> roomSaves) {
        try {
            //添加房间时，无条件更新云对讲设备（即使项目没有云对讲，消费者会自行过滤）
            JSONArray jsonArray = new JSONArray();
            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            List<Map<String, Object>> saveRoomList = new ArrayList<>();
            for (RoomInfoPO roomInfoPO : roomSaves) {
                JSONObject jsonObject = new JSONObject();
                saveRoomList.add(SqlUtil.durableData(roomInfoPO, PlatformConstants.TABLE_SAVE));
                jsonObject.put("roomId",roomInfoPO.getRoomId());
                jsonArray.add(jsonObject);
            }
            int intRes = iCloudTalkSDKServerRoomDao.batchSave(saveRoomList);

            String projectId = roomSaves.get(0).getProjectId();
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM,jsonArray,projectId);
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",deviceBusinessChangeLogPOS);
            // 发送消息队列
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

            return intRes;
        } catch (Exception e) {
            throw new DataAccessException("【CloudTalk_SDK_build_update】更新楼栋异常", e);
        }
    }

    /**
     * <desc>
     *      云对讲SDK批量添加用户房间信息
     * <desc/>
     *
     * @param saveAppUserDTOs 用户房间信息
     * @return
     * @author JuGuang.S
     * @createDate 2018/05/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Map<String, Object> addUserRoomInfo(List<SDKSaveAppUserDTO> saveAppUserDTOs) {
        try {
            if (saveAppUserDTOs == null || saveAppUserDTOs.isEmpty()) {
                return null;
            }
            Date currentTime = new Date();
            Set<String> userIdSet = new HashSet<>();
            List<Map<String, String>> returnList = new ArrayList<>();
            int existUserCount = 0;
            for (SDKSaveAppUserDTO saveAppUserDTO : saveAppUserDTOs) {
                List<AppUserRoomPO> updateUserRoomList = new ArrayList<>();
                List<Map<String, Object>> saveUserRoomList = new ArrayList<>();
                String projectId = saveAppUserDTO.getProjectId();
                String authUserId = saveAppUserDTO.getAuthUserId();
                Integer houseType = saveAppUserDTO.getHouseType();
                String phoneNum = saveAppUserDTO.getUserPhone();
                List<SDKRoomInfoSaveDTO> userRoomList = saveAppUserDTO.getUserRoomList();

                int machineId = 1;
                int hashCodeV = UUID.randomUUID().toString().hashCode();
                if(hashCodeV < 0) {//有可能是负数
                    hashCodeV = - hashCodeV;
                }
                String lykzUserId = String.format("%s%s",phoneNum,machineId + String.format("%015d", hashCodeV));

                //处理用户表和用户项目表
                String userId = this.userProjectHandler(saveAppUserDTO,lykzUserId);

                //处理用户房间表
                if (userRoomList != null && !userRoomList.isEmpty()) {
                    JSONArray jsonArray = new JSONArray();
                    for (SDKRoomInfoSaveDTO userRoomDTO : userRoomList) {
                        String roomId = userRoomDTO.getRoomId();

                        //查询该用户是否在该房间内存在：不存在才进行操作
                        Map<String, Object> getUserRoomParam = new HashMap<>();
                        getUserRoomParam.put("projectId", projectId);
                        getUserRoomParam.put("roomId", roomId);
                        getUserRoomParam.put("userId", userId);
                        List<AppUserRoomPO> userRoomPOS = iCloudTalkSDKServerSaveUserRoomDao.getUserRoom(getUserRoomParam);
                        if (userRoomPOS == null || userRoomPOS.isEmpty()) {
                            AppUserRoomPO appUserRoomPO = new AppUserRoomPO(userId, projectId, userRoomDTO.getBuildId(),
                                    userRoomDTO.getUnitId(), userRoomDTO.getRoomNum(), roomId,
                                    AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType(), houseType,
                                    AppUserRoomSourceEnum.USERROOM_SOURCE_ADD.getType(), DataStatusEnum.NORMAL.getType(), currentTime);
                            appUserRoomPO.setUpdateTime(currentTime);
                            saveUserRoomList.add(SqlUtil.durableData(appUserRoomPO, PlatformConstants.TABLE_SAVE));
                            userIdSet.add(userId);
                        } else {
                            //如果该用户在该房间已经存在，更新时间和状态
                            AppUserRoomPO appUserRoomPO = userRoomPOS.get(0);
                            appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
                            appUserRoomPO.setUpdateTime(currentTime);
                            updateUserRoomList.add(appUserRoomPO);
                            existUserCount++;
                        }

                        //业务指令参数JSONArray
                        JSONObject json = new JSONObject();
                        json.put("userId", userId);
                        json.put("roomId", roomId);
                        jsonArray.add(json);
                    }
                    //推送住户所有业主身份房间信息
                    if(!jsonArray.isEmpty()){
                        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                                new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_ROOM, jsonArray.toJSONString(), projectId);
                        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
                        changeLogPOS.add(deviceBusinessChangeLogPO);
                        if (changeLogPOS != null && !changeLogPOS.isEmpty()) {
                            JSONObject datajs = new JSONObject();
                            datajs.put("data",changeLogPOS);
                            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                                    JsonUtil.toJSON(datajs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                        }
                    }
                }

                //持久化数据
                if (updateUserRoomList != null && !updateUserRoomList.isEmpty()) {
                    iCloudTalkSDKServerSaveUserRoomDao.batchUpdateUserRoomInfo(updateUserRoomList);
                }
                if (saveUserRoomList != null && !saveUserRoomList.isEmpty()) {
                    iCloudTalkSDKServerSaveUserRoomDao.batchSaveUserRoomInfo(saveUserRoomList);
                }

                CloudTalkUserAuthDTO UserAuthDTO = new CloudTalkUserAuthDTO(new ArrayList<>(userIdSet), authUserId, projectId);
                JSONObject dataJs = new JSONObject();
                dataJs.put("data", JSONObject.toJSON(UserAuthDTO));
                this.cloudTalkUserDeviceAuthAddressProducer(dataJs);

                Map<String, Object> map = iCloudTalkSDKServerProjectDao.getSipInfoByProjectId(projectId);
                //根据userId获取用户的sipAccount\
                String account = iCloudTalkSDKServerProjectDao.getSipAccountByUserId(userId);
                if(StringUtils.isNotEmpty(account)){
                    lykzUserId = account;
                }
                String sipAccountData = String.format("%s@%s:%s", lykzUserId, map.get("sipAddress"), map.get("sipPort"));

                Map<String, String> returnMap = new HashMap<>();
                returnMap.put("userId", userId);
                returnMap.put("sipAccount", sipAccountData);
                returnList.add(returnMap);

            }
            Map<String, Object> countMap = new HashMap<>();
            countMap.put("existUser", existUserCount);
            countMap.put("addUserCount", userIdSet.size());
            countMap.put("sipArr", returnList);
            return countMap;
        } catch (Exception e) {
            throw new DataAccessException("【云对讲SDK服务端_CloudTalkSDKServerProjectServiceImpl_addUserRoomInfo】批量添加用户房间信息异常", e);
        }
    }

    /**
     * <desc>
     *      获取用户设备权限地址生产者
     * <desc/>
     *
     * @param dataJs 生产者发送的数据
     * @return
     * @author JuGuang.S
     * @createDate 2018/05/18
     */
    private void cloudTalkUserDeviceAuthAddressProducer(JSONObject dataJs) throws Exception {
        messageSender.send(RabbitMQConstant.RABBITMQ_CLOUD_TALK_SDK_USER_SAVE_DEVICE_AUTH_INFO_QUEUE,
                JSON.toJSONString(dataJs), RabbitMQConstant.RABBITMQ_USER_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_TALK_SDK_USER_SAVE_DEVICE_AUTH_INFO_ROUTING_KEY);
    }

    /**
     * <desc>
     *      添加App用户时，对app_user_info,app_user_project表的影响
     * <desc/>
     *
     * @param sdkSaveAppUserDTO 添加用户数据DTO
     * @return 添加后的userId
     * @author JuGuang.S
     * @createDate 2018/05/17
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String userProjectHandler(SDKSaveAppUserDTO sdkSaveAppUserDTO,String lykzUserId) throws Exception {
        String phoneNum = sdkSaveAppUserDTO.getUserPhone();
        String projectId = sdkSaveAppUserDTO.getProjectId();

        //通过手机号查询被授权人是否在数据库中已经存在
        Date currentTime = new Date();
        String userId = "";
        AppUserInfoPO appUser = iCloudTalkSDKServerSaveUserRoomDao.getUserByPhoneNum(phoneNum);
        if (appUser == null) {
            //查询手机的用户不存在,添加app_user_info
            userId = sdkSaveAppUserDTO.getUserId();
            appUser = new AppUserInfoPO(userId, sdkSaveAppUserDTO.getRealName(), sdkSaveAppUserDTO.getRealName(), Md5EncryptUtil.md5(phoneNum), phoneNum, AppUserGenderEnum.USERINFO_GENDER_MAN.getType(), sdkSaveAppUserDTO.getToken());
            appUser.setStatus(DataStatusEnum.NORMAL.getType());
            appUser.setRealName(sdkSaveAppUserDTO.getRealName());
            appUser.setGender(sdkSaveAppUserDTO.getGender());
            appUser.setCreateTime(currentTime);
            iCloudTalkSDKServerSaveUserRoomDao.save(SqlUtil.durableData(appUser, PlatformConstants.TABLE_SAVE));
            //异步创建灵云快智账号
            Map<String,Object> params=new HashMap<>();
            params.put("userId",userId );
            params.put("phoneNum", phoneNum);
            params.put("lykzAppId",sdkSaveAppUserDTO.getLykzAppId());
            params.put("projectId",projectId);
            params.put("lykzUserId",lykzUserId);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_PROJECT_CLOUD_TALK_SDK_CREATE_LYKZ_ACCOUNT_QUEUE,
                    JSON.toJSONString(params),
                    RabbitMQConstant.RABBITMQ_USER_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_PROJECT_CLOUD_TALK_SDK_CREATE_LYKZ_ACCOUNT_KEY
            );
        } else {
            userId = appUser.getUserId();
            appUser.setStatus(DataStatusEnum.NORMAL.getType());
            appUser.setRealName(sdkSaveAppUserDTO.getRealName());
            appUser.setGender(sdkSaveAppUserDTO.getGender());
            appUser.setUpdateTime(currentTime);
            iCloudTalkSDKServerSaveUserRoomDao.update(SqlUtil.durableData(appUser, PlatformConstants.TABLE_UPDATE));

            // 处理用户项目表
            Map<String, Object> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("userId", userId);
            List<AppUserProjectPO> userProjectPOs = iCloudTalkSDKServerSaveUserRoomDao.getUserProjectByParams(params);
            AppUserProjectPO userProjectPO = null;
            if (userProjectPOs == null || userProjectPOs.isEmpty()) {
                userProjectPO = new AppUserProjectPO(userId, projectId, AppUserProjectTypeEnum.USERPROJECT_TYPE_SELF.getType().toString(),
                        "000000", AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_ENABLE.getType().toString(),
                        AppUserProjectUserTypeEnum.USERPROJECT_USERTYPE_ORDINARY.getType(), DataStatusEnum.NORMAL.getType(), currentTime);
                Map<String,String> map = this.getLykzCloudIntercomAccountByMoblie(phoneNum,sdkSaveAppUserDTO.getLykzAppId());
                if(map!=null){
                    userProjectPO.setSipAccount(map.get("lykzUserId"));
                }
                String sipPsd = Md5EncryptUtil.md5(userId + phoneNum).toLowerCase();
                userProjectPO.setSipPsd(sipPsd);
                iCloudTalkSDKServerSaveUserRoomDao.save(SqlUtil.durableData(userProjectPO, PlatformConstants.TABLE_SAVE));
            } else {
                userProjectPO = userProjectPOs.get(0);
                userProjectPO.setUpdateTime(currentTime);
                userProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
                iCloudTalkSDKServerSaveUserRoomDao.updateUserProjectInfo(userProjectPO);
            }
        }
        /*Thread.sleep(1500);

        // 处理用户项目表
        Map<String, Object> params = new HashMap<>();
        params.put("projectId", projectId);
        params.put("userId", userId);
        List<AppUserProjectPO> userProjectPOs = iCloudTalkSDKServerSaveUserRoomDao.getUserProjectByParams(params);
        AppUserProjectPO userProjectPO = null;
        if (userProjectPOs == null || userProjectPOs.isEmpty()) {
            userProjectPO = new AppUserProjectPO(userId, projectId, AppUserProjectTypeEnum.USERPROJECT_TYPE_SELF.getType().toString(),
                    "000000", AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_ENABLE.getType().toString(),
                    AppUserProjectUserTypeEnum.USERPROJECT_USERTYPE_ORDINARY.getType(), DataStatusEnum.NORMAL.getType(), currentTime);
            Map<String,String> map = this.getLykzCloudIntercomAccountByMoblie(phoneNum,sdkSaveAppUserDTO.getLykzAppId());
            if(map!=null){
                userProjectPO.setSipAccount(map.get("lykzUserId"));
            }
            String sipPsd = Md5EncryptUtil.md5(userId + phoneNum).toLowerCase();
            userProjectPO.setSipPsd(sipPsd);
            iCloudTalkSDKServerSaveUserRoomDao.save(SqlUtil.durableData(userProjectPO, PlatformConstants.TABLE_SAVE));
            this.cloudSipHandler(projectId,map.get("lykzUserId"), sipPsd, null);
        } else {
            userProjectPO = userProjectPOs.get(0);
            userProjectPO.setUpdateTime(currentTime);
            userProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
            iCloudTalkSDKServerSaveUserRoomDao.updateUserProjectInfo(userProjectPO);
        }*/
        return userId;
    }

    public static void main(String[] args) {
        System.out.println(Md5EncryptUtil.md5("18899889988"));
    }

    /**
     * <desc>
     *      根据手机号查询灵云快智云对讲用户账号
     * </desc>
     *
     * @param phoneNum 手机号
     * @return
     * @author Juguang.S
     * @createDate 2018/08/23
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Map<String,String> getLykzCloudIntercomAccountByMoblie(String phoneNum,String lykzAppid) throws Exception {

        //SigParameter MD5（账户Id + 账户授权令牌 + 时间戳），共32位(注:转成大写)
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowTime = sd.format(new Date());
        String sigParameter = Md5EncryptUtil.md5(String.format("%s%s%s",LYKZ_ACCOUNT_SID,LYKZ_ACCOUNT_TOKEN,nowTime)).toUpperCase();
        String host = "http://"+LYKZ_URL+":"+LYKZ_PORT+"/ucsrtc-rest-api/"+LYKZ_SOFT_VERSION+"/Accounts/"+LYKZ_ACCOUNT_SID;
        String path = "/ClientsByMobile";
        String method = "GET";

        final Base64.Encoder encoder = Base64.getEncoder();
        final String context = String.format("%s%s%s",LYKZ_ACCOUNT_SID,":",nowTime);
        final byte[] textByte = context.getBytes("UTF-8");
        //编码
        final String authorization = encoder.encodeToString(textByte);

        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", authorization);
        headers.put("Accept", "application/json;");
        headers.put("Content-Type", "application/json;charset=utf-8");

        Map<String, String> querys = new HashMap<>();
        querys.put("sig",sigParameter);
        if(StringUtils.isNotEmpty(lykzAppid)){
            querys.put("appId",lykzAppid);
        }else{
            querys.put("appId",LYKZ_APPID);
        }
        querys.put("mobile",phoneNum);

        HttpResponse response = HttpProtocolUtil.doGet(host, path, method, headers, querys);


        if (response != null && response.getEntity() != null) {
            Map<String, Object> jsonToMap = JsonUtil.JsonToMap(EntityUtils.toString(response.getEntity()));
            if (jsonToMap != null && !jsonToMap.isEmpty()){
                Map<String, Object> jsonToMapResp = JsonUtil.JsonToMap(jsonToMap.get("resp").toString());
                if(jsonToMapResp != null && !jsonToMapResp.isEmpty()){
                    String respCode = jsonToMapResp.get("respCode").toString();
                    if(respCode.equals("000000")){
                        String client = jsonToMapResp.get("client").toString();
                        Map<String, Object> jsonToMapClient = JsonUtil.JsonToMap(client);
                        Map<String,String> resultMap = new HashMap<>();
                        resultMap.put("clientNumber",jsonToMapClient.get("clientNumber").toString());
                        resultMap.put("clientPwd",jsonToMapClient.get("clientPwd").toString());
                        resultMap.put("loginToken",jsonToMapClient.get("loginToken").toString());
                        resultMap.put("createDate",jsonToMapClient.get("createDate").toString());
                        resultMap.put("lykzUserId",jsonToMapClient.get("userId").toString());
                        resultMap.put("mobile",jsonToMapClient.get("mobile").toString());
                        System.out.println(resultMap.toString());
                        return resultMap;
                    }else{
                        return null;
                    }

                }
            }
        }
        return null;
    }

    /**
     * <desc>
     *      对sip数据源中的Sip账号进行添加，更新，或删除操作
     * <desc/>
     * @param  addOrUpdateUserName  根据userName添加或更新Sip数据源的数据（存在则更新，不存在则添加）
     * @param  addOrUpdatePassword  添加或更新Sip数据源的password
     * @param  delUserName  根据userName删除Sip数据源的数据
     * @author Biao.R
     * @createDate 2018/1/9
     */
    public void cloudSipHandler(String projectId,String addOrUpdateUserName, String addOrUpdatePassword, String delUserName) throws Exception {
        PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId,addOrUpdateUserName, addOrUpdatePassword, delUserName);
        JSONObject js = new JSONObject();
        js.put("data",JSONObject.toJSON(subscriberHanlerDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);
    }

    /**
     * <desc>
     *      云对讲SDK查看该项目下是否存在指定用户
     * <desc/>
     *
     * @param projectId 项目编号
     * @param userId    用户Id
     * @return
     * @author JuGuang.S
     * @createDate 2018/05/21
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer userIsExist(String projectId, String userId) {
        return iCloudTalkSDKServerProjectDao.userIsExist(projectId, userId);
    }

    /**
     * <desc>
     *      云对讲SDK修改项目下指定用户的禁用启用状态
     * <desc/>
     *
     * @param param 项目编号、用户ID、所要改变的状态
     * @return
     * @author JuGuang.S
     * @createDate 2018/05/21
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void modifyUserStatus(Map<String, Object> param) {

        try {
            iCloudTalkSDKServerProjectDao.modifyUserStatus(param);

            //推送设备云对讲重启指令
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("projectId", param.get("projectId"));
            jsonObject.put("userId", param.get("userId"));
            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            DeviceBusinessChangeLogPO changeLogPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, jsonObject, param.get("projectId").toString());
            deviceBusinessChangeLogPOS.add(changeLogPO);
            // 推送云对讲指令
            if (deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()) {
                this.pushCloudIntercom(deviceBusinessChangeLogPOS);
            }

            List<AppUserRoomPO> appUserRoomPOS = iCloudTalkSDKServerProjectDao.getHouseHoldRoomAtNormalStatus(param);
            if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                JSONArray jsonArray = new JSONArray();
                for (AppUserRoomPO appUserRoomPO:appUserRoomPOS) {
                    JSONObject json = new JSONObject();
                    json.put("roomId", appUserRoomPO.getRoomId());
                    jsonArray.add(json);
                }
                //推送住户所有业主身份房间信息
                //云对讲
                List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
                DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                        new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM, jsonArray.toJSONString(), param.get("projectId").toString());
                changeLogPOS.add(deviceBusinessChangeLogPO);
                this.pushCloudIntercom(changeLogPOS);
            }


        } catch (Exception e) {
            throw new DataAccessException("【云对讲SDK服务端_CloudTalkSDKServerProjectServiceImpl_modifyUserStatus】修改项目下的用户状态异常", e);
        }

    }

    /**
     * <desc>
     *      向设备推送设备云对讲指令
     * <desc/>
     *
     * @param   changeLogPOS     云对讲变更指令集合
     * @author JuGuang.S
     * @createDate 2018/05/21
     */
    public void pushCloudIntercom(List<DeviceBusinessChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云对讲
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      云对讲设备同步业务生产者
     * <desc/>
     *
     * @param dataJs  生产者发送的数据
     * @return
     * @author zhangs
     * @createDate 2018/02/25
     */
    private void smartCommunityOrdersProducer(JSONObject dataJs) throws Exception {
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
    }

    /**
     * <desc>
     *      根据projectId,buildNum,unitNum和roomNum查询房间信息
     * <desc/>
     * @param       params      待查询的参数集
     * @return      符合的房间对象集
     * @author JuGuang.S
     * @createDate 2018/05/21
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<RoomInfoPO> getRoomByPiBnUnRn(Map<String, Object> params) {
        if(!params.isEmpty()){
            return iCloudTalkSDKServerProjectDao.getRoomByPiBnUnRn(params);
        }
        return null;
    }

    /**
     * <desc>
     *      根据projectId,buildNum,unitNum和roomNum查询该房间下是否已有业主
     * <desc/>
     * @param       params      待查询的参数集
     * @return      符合的房间对象集
     * @author JuGuang.S
     * @createDate 2018/12/6
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer getIsOwnerUser(Map<String, Object> params) {
        if(!params.isEmpty()){
            return iCloudTalkSDKServerProjectDao.getIsOwnerUser(params);
        }
        return null;
    }

    /**
     * <desc>
     *      根据项目ID和pubKey查询单个项目
     * <desc/>
     * @param  desProjectId  待查询项目ID
     * @param  pubKey  项目密钥
     * @return  ProjectPO  返回对象
     * @author JuGuang.S
     * @createDate 2018/05/11
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ProjectPO getByProjectIdAndPubKey(String desProjectId,String pubKey) {
        return iCloudTalkSDKServerProjectDao.getByProjectIdAndPubKey(desProjectId,pubKey);
    }

    /**
     * <desc>
     *      根据项目编号查询sip的ip和port
     * <desc/>
     * @param  projectId  查询项目ID
     * @return  Map<String,String>  返回sip的ip和port
     * @author JuGuang.S
     * @createDate 2018/05/14
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Map<String,Object> getSipInfoByProjectId(String projectId) {
        return iCloudTalkSDKServerProjectDao.getSipInfoByProjectId(projectId);
    }

    /**
     * <desc>
     *      获取项目的楼栋信息列表
     * </desc>
     *
     * @param cloudTalkSDKServerGetBuildListDTO 查询参数
     * @return 楼栋信息列表
     * @author wangzhi
     * @createDate 2018/05/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public CloudTalkSDKServerGetBuildVO getBuildList(CloudTalkSDKServerGetBuildListDTO cloudTalkSDKServerGetBuildListDTO) throws Exception {
        if (cloudTalkSDKServerGetBuildListDTO.getPageSize() == null || cloudTalkSDKServerGetBuildListDTO.getPageSize() == 0){
            cloudTalkSDKServerGetBuildListDTO.setPageSize(10);
        }
        if (cloudTalkSDKServerGetBuildListDTO.getPageNo() == null || cloudTalkSDKServerGetBuildListDTO.getPageNo() == 0){
            cloudTalkSDKServerGetBuildListDTO.setPageNo(1);
        }
        cloudTalkSDKServerGetBuildListDTO.setPageNo((cloudTalkSDKServerGetBuildListDTO.getPageNo() - 1) * cloudTalkSDKServerGetBuildListDTO.getPageSize());
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(cloudTalkSDKServerGetBuildListDTO);
        CloudTalkSDKServerGetBuildVO cloudTalkSDKServerGetBuildVO = iCloudTalkSDKServerBuildDao.getProjectInformation(params);
        Integer totalNumber = iCloudTalkSDKServerBuildDao.getBuildTotalNumber(params);
        cloudTalkSDKServerGetBuildVO.setTotalNumber(totalNumber);
        List<CloudTalkSDKServerBuildInfoArrVO> buildInfoArr = iCloudTalkSDKServerBuildDao.getBuildInfoArr(params);
        cloudTalkSDKServerGetBuildVO.setBuildInfoArr(buildInfoArr);
        return cloudTalkSDKServerGetBuildVO;
    }

    /**
     * <desc>
     *      获取项目楼栋的单元信息列表
     * </desc>
     *
     * @param cloudTalkSDKServerGetUnitListDTO 查询参数
     * @return 项目楼栋的单元信息列表
     * @author wangzhi
     * @createDate 2018/05/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public CloudTalkSDKServerGetUnitVO getUnitList(CloudTalkSDKServerGetUnitListDTO cloudTalkSDKServerGetUnitListDTO) throws Exception {
        if (cloudTalkSDKServerGetUnitListDTO.getPageSize() == null || cloudTalkSDKServerGetUnitListDTO.getPageSize() == 0){
            cloudTalkSDKServerGetUnitListDTO.setPageSize(10);
        }
        if (cloudTalkSDKServerGetUnitListDTO.getPageNo() == null || cloudTalkSDKServerGetUnitListDTO.getPageNo() == 0){
            cloudTalkSDKServerGetUnitListDTO.setPageNo(1);
        }
        cloudTalkSDKServerGetUnitListDTO.setPageNo((cloudTalkSDKServerGetUnitListDTO.getPageNo() - 1) * cloudTalkSDKServerGetUnitListDTO.getPageSize());
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(cloudTalkSDKServerGetUnitListDTO);
        CloudTalkSDKServerGetUnitVO cloudTalkSDKServerGetUnitVO = iCloudTalkSDKServerUnitDao.getProjectInformation(params);
        Integer totalNumber = iCloudTalkSDKServerUnitDao.getUnitTotalNumber(params);
        cloudTalkSDKServerGetUnitVO.setTotalNumber(totalNumber);
        List<CloudTalkSDKServerUnitInfoArrVO> unitInfoArr = iCloudTalkSDKServerUnitDao.getUnitInfoArr(params);
        cloudTalkSDKServerGetUnitVO.setUnitInfoArr(unitInfoArr);
        cloudTalkSDKServerGetUnitVO.setBuildNum(cloudTalkSDKServerGetUnitListDTO.getBuildNum());
        return cloudTalkSDKServerGetUnitVO;
    }

    /**
     * <desc>
     *      根据appId查询项目列表
     * <desc/>
     * @param       pageDTO      用户名称
     * @return      项目集
     * @author Qiang.S
     * @createDate 2018/05/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<SDKServerProjectInfoListPageVO> getProjectList(CloudTalkSDKServerGetProjectInfoPageDTO pageDTO) throws Exception {
        if (StringUtils.isEmpty(pageDTO.getPageSize())){
            pageDTO.setPageSize("15");
        }
        if (StringUtils.isEmpty(pageDTO.getCurrentPage())){
            pageDTO.setCurrentPage("1");
        }
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为10
        Page<SDKServerProjectInfoListPageVO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());//默认10
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());//默认1
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        //填充返回数据集
        page.setRows(iCloudTalkSDKServerProjectDao.getProjectListPage(params), iCloudTalkSDKServerProjectDao.getProjectListPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      上传苹果推送证书
     * </desc>
     *
     * @return 受影响的行数
     * @author wangzhi
     * @createDate 2018/11/22
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer uploadApplePush(CloudTalkSDKServerUploadApplePushDTO cloudTalkSDKServerUploadApplePushDTO) throws Exception {
        String url = iCloudTalkSDKServerProjectDao.getUrlByProjectId(cloudTalkSDKServerUploadApplePushDTO.getProjectId());
        if (StringUtils.isBlank(url)) {
            Date nowTime = new Date();
            ApplePushCciePO applePushCciePO = new ApplePushCciePO();
            applePushCciePO.setApplePushCcieId(LogicIdUtil.bussinessId());
            applePushCciePO.setProjectId(cloudTalkSDKServerUploadApplePushDTO.getProjectId());
            applePushCciePO.setUrl(cloudTalkSDKServerUploadApplePushDTO.getUrl());
            applePushCciePO.setVoip(cloudTalkSDKServerUploadApplePushDTO.getVoip());
            applePushCciePO.setProduction(cloudTalkSDKServerUploadApplePushDTO.getProduction());
            applePushCciePO.setPassword(cloudTalkSDKServerUploadApplePushDTO.getPassword());
            applePushCciePO.setStatus(DataStatusEnum.NORMAL.getType());
            applePushCciePO.setCreateTime(nowTime);
            applePushCciePO.setUpdateTime(nowTime);
            Map<String, Object> map = SqlUtil.durableData(applePushCciePO, PlatformConstants.TABLE_SAVE);
            return iCloudTalkSDKServerProjectDao.save(map);
        }
        return iCloudTalkSDKServerProjectDao.updateApplePush(cloudTalkSDKServerUploadApplePushDTO.getProjectId(),cloudTalkSDKServerUploadApplePushDTO.getUrl());
    }

    /**
     * <desc>
     *      根据项目编号和角色为开发者账号查询当前项目绑定的灵云快智的应用账号信息
     * <desc/>
     * @param  projectId  查询项目ID
     * @param  roleId  开发者账号
     * @return
     * @author JuGuang.S
     * @createDate 2018/12/21
     */
    @Override
    public String getBingLykzAppId(String projectId, String roleId,String appId) {
        //根据项目编号和角色为开发者账号查询当前项目绑定的灵云快智的应用账号信息
        return iCloudTalkSDKServerProjectDao.getBingLykzAppId(projectId,roleId,appId);
    }
}
